package com.biblioteca.dao;

import com.biblioteca.persistencia.Libro;
import com.biblioteca.persistencia.Noticia;
import com.biblioteca.persistencia.Voto;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class GenericDaoImplementation<T, PK extends Serializable> implements GenericDao<T, PK> {

    @PersistenceContext
    EntityManager em;

    @Transactional
    @Override
    public void update(T object) {
        em.merge(object);       
        em.flush();
    }

    @Transactional
    @Override
    public void remove(T object) {
        em.remove(em.merge(object));
    }

    @Transactional
    @Override
    public void remove(Class<T> typeClass, PK clave) {
        T object = em.find(typeClass, clave);
        em.remove(em.merge(object));

    }

    @Transactional
    @Override
    public int removeAll(Class<T> typeClass) {
        String sql = "DELETE FROM " + typeClass.getSimpleName() + " c";
        return em.createQuery(sql).executeUpdate();
    }

    @Transactional
    @Override
    public void insert(T t) {
        em.persist(t);
        System.out.println("insert t= " + t);
        em.flush();
    }

    @Transactional
    @Override
    public void cerrar() {
        em.close();
    }

    @Transactional
    @Override
    public List<T> getPaginated(Class<T> typeClass, int startPosition,
        int maxResult) {
        // TODO Auto-generated method stub
        return null;
    }

    @Transactional
    @Override
    public List<T> getOrderedPaginated(Class<T> typeClass, int startPosition,
            int maxResult, String order, int dir) {
        // TODO Auto-generated method stub
        return null;
    }

    @Transactional
    @Override
    public List<T> getAll(Class<T> typeClass) {
        final StringBuilder sql = new StringBuilder("select c from ").append(
                typeClass.getSimpleName()).append(" c");
        return (List<T>) em.createQuery(sql.toString()).getResultList();
    }

    @Transactional
    @Override
    public List<Noticia> getAllNoticias() {
        final StringBuilder sql = new StringBuilder("select c from Noticia c ORDER by fecha DESC");
        return (List<Noticia>) em.createQuery(sql.toString()).getResultList();
    }

    @Transactional
    @Override
    public Integer countAll(Class<T> typeClass) {
        final StringBuilder sql = new StringBuilder("select c from ").append(
                typeClass.getSimpleName()).append(" c");
        List <T> datos = em.createQuery(sql.toString()).getResultList();
        return datos.size();

    }

    @Transactional
    @Override
    public T findByPK(Class<T> typeClass, PK id) {
        return em.find(typeClass, id);
    }

    @Transactional
    @Override
    public T find(Class<T> typeClass, PK clave) {
        return em.find(typeClass, clave);
    }
}
